package com.aiyige.im;

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;

import com.aiyige.MyApp;
import com.aiyige.R;
import com.aiyige.arouter.config.ARouterConfig;
import com.aiyige.base.api.JsonUtil;
import com.aiyige.base.eventbus.EventKickOff;
import com.aiyige.im.mixpush.DemoPushContentProvider;
import com.aiyige.im.model.CustomAttachParser;
import com.aiyige.im.model.CustomMessageType;
import com.aiyige.im.model.CustomMsgData;
import com.aiyige.im.model.UserPreferences;
import com.aiyige.im.model.attachment.SubjectAttachment;
import com.aiyige.im.model.attachment.UserAttachment;
import com.aiyige.im.model.viewHolder.MsgViewHolderSubject;
import com.aiyige.im.model.viewHolder.MsgViewHolderUser;
import com.aiyige.model.AiyigeExceptionModel;
import com.aiyige.page.login.model.impl.LoginManager;
import com.aiyige.page.my.settings.ConfigUltis;
import com.aiyige.page.user.UserPage;
import com.aiyige.utils.AccountUtil;
import com.aiyige.utils.ListUtil;
import com.aiyige.utils.ToastX;
import com.aiyige.utils.crash.CrashUtils;
import com.alibaba.android.arouter.launcher.ARouter;
import com.netease.nim.uikit.api.NimUIKit;
import com.netease.nim.uikit.api.model.main.CustomPushContentProvider;
import com.netease.nim.uikit.api.model.session.SessionEventListener;
import com.netease.nim.uikit.business.session.module.MsgForwardFilter;
import com.netease.nim.uikit.business.session.module.MsgRevokeFilter;
import com.netease.nim.uikit.impl.NimUIKitImpl;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.Observer;
import com.netease.nimlib.sdk.StatusBarNotificationConfig;
import com.netease.nimlib.sdk.StatusCode;
import com.netease.nimlib.sdk.auth.AuthServiceObserver;
import com.netease.nimlib.sdk.msg.MessageBuilder;
import com.netease.nimlib.sdk.msg.MsgService;
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
import com.netease.nimlib.sdk.msg.model.CustomMessageConfig;
import com.netease.nimlib.sdk.msg.model.IMMessage;

import org.greenrobot.eventbus.EventBus;

import java.util.Map;

/**
 * 会话助手（聊天，发自定义消息等）
 * xiachao
 */
public class SessionHelper {
    public static SessionHelper getInstance() {
        return instance;
    }

    final static SessionHelper instance = new SessionHelper();

    /**
     * 初始化注册解析器，在application的主线程中初始化
     */
    public static void init() {
        // 注册自定义消息附件解析器
        NIMClient.getService(MsgService.class).registerCustomAttachmentParser(new CustomAttachParser());

        // 注册自定义消息的subject内容
        NimUIKit.registerMsgItemViewHolder(SubjectAttachment.class, MsgViewHolderSubject.class);

        // 注册自定义消息的user名片
        NimUIKit.registerMsgItemViewHolder(UserAttachment.class, MsgViewHolderUser.class);

        // 注册消息转发过滤器
        registerMsgForwardFilter();

        // 注册消息撤回过滤器
        registerMsgRevokeFilter();

        // 设置会话中点击事件响应处理
        setSessionListener();

        // 设置地理位置提供者。如果需要发送地理位置消息，该参数必须提供。如果不需要，可以忽略。
        NimUIKit.setLocationProvider(new NimLocationProvider());

        initNotificationConfig();

//        otherImLoginCallback();

        // 添加自定义推送文案以及选项，请开发者在各端（Android、IOS、PC、Web）消息发送时保持一致，以免出现通知不一致的情况
        NimUIKit.setCustomPushContentProvider(new DemoPushContentProvider());

    }


    /**
     * 用户状态变化
     */
    static Observer<StatusCode> userStatusObserver = new Observer<StatusCode>() {

        @Override
        public void onEvent(StatusCode code) {
            if (code.wontAutoLogin()) {
                // 被踢出、账号被禁用、密码错误等情况，自动登录失败，需要返回到登录界面进行重新登录操作
                LoginManager.getInstance().logout(false);
                EventBus.getDefault().post(new EventKickOff());
            }
        }
    };

    public static void otherImLoginCallback() {
        NIMClient.getService(AuthServiceObserver.class).observeOnlineStatus(userStatusObserver, true);
    }

    public static void otherImLogoutCallback() {
        NIMClient.getService(AuthServiceObserver.class).observeOnlineStatus(userStatusObserver, false);
    }


    public static void initNotificationConfig() {
        // 初始化消息提醒
//        NIMClient.toggleNotification(true);
        NIMClient.toggleNotification(ConfigUltis.isEnableMessagePush());

        // 加载状态栏配置
        StatusBarNotificationConfig statusBarNotificationConfig = UserPreferences.getStatusConfig();
        if (statusBarNotificationConfig == null) {
            statusBarNotificationConfig = ImCache.getNotificationConfig();
            UserPreferences.setStatusConfig(statusBarNotificationConfig);
        }
        // 更新配置
        NIMClient.updateStatusBarNotificationConfig(statusBarNotificationConfig);
    }


    private static void setSessionListener() {
        SessionEventListener listener = new SessionEventListener() {
            @Override
            public void onAvatarClicked(Context context, IMMessage message) {
                RecentContactHelper.getInstance().getNimUserInfo(message.getFromAccount(), new RecentContactHelper.RequestUserIdCallback() {
                    @Override
                    public void onSuccess(String userId) {
                        if (!TextUtils.isEmpty(userId)) {
                            UserPage.start(userId);
                        }
                    }
                });
            }

            @Override
            public void onAvatarLongClicked(Context context, IMMessage message) {
                // 一般用于群组@功能，或者弹出菜单，做拉黑，加好友等功能
                RecentContactHelper.getInstance().getNimUserInfo(message.getFromAccount(), new RecentContactHelper.RequestUserIdCallback() {
                    @Override
                    public void onSuccess(String userId) {
                        if (!TextUtils.isEmpty(userId)) {
                            UserPage.start(userId);
                        }
                    }
                });
            }

            @Override
            public void onAckMsgClicked(Context context, IMMessage message) {
                // 已读回执事件处理，用于群组的已读回执事件的响应，弹出消息已读详情
//                AckMsgInfoActivity.start(context, message);
            }
        };

        NimUIKit.setSessionListener(listener);
    }


    /**
     * 消息撤回过滤器
     */
    private static void registerMsgRevokeFilter() {
        NimUIKit.setMsgRevokeFilter(new MsgRevokeFilter() {
            @Override
            public boolean shouldIgnore(IMMessage message) {
//                if (message.getAttachment() != null
//                        && (message.getAttachment() instanceof AVChatAttachment)) {
//                    // 视频通话消息和白板消息，红包消息 不允许撤回
//                    return true;
//                } else if (DemoCache.getAccount().equals(message.getSessionId())) {
//                    // 发给我的电脑 不允许撤回
//                    return true;
//                }
                return false;//均可撤回
            }
        });
    }

    /**
     * 消息转发过滤器
     */
    private static void registerMsgForwardFilter() {
        NimUIKit.setMsgForwardFilter(new MsgForwardFilter() {
            @Override
            public boolean shouldIgnore(IMMessage message) {
//                if (message.getDirect() == MsgDirectionEnum.In
//                        && (message.getAttachStatus() == AttachStatusEnum.transferring
//                        || message.getAttachStatus() == AttachStatusEnum.fail)) {
//                    // 接收到的消息，附件没有下载成功，不允许转发
//                    return true;
//                }else if (message.getMsgType() == MsgTypeEnum.robot && message.getAttachment() != null && ((RobotAttachment) message.getAttachment()).isRobotSend()) {
//                    return true; // 如果是机器人发送的消息 不支持转发
//                }
                return false;
            }
        });
    }


    /**
     * 发送moment消息
     *
     * @param accid
     * @param imageUrl
     * @param title
     * @param desc
     * @param router
     */
    public void sendMomentMessage(String accid, String subject, String imageUrl, String title, String desc, String router, String price, String linePrice) {
        SubjectAttachment attachment = new SubjectAttachment();
        attachment.setKeyType(CustomMessageType.moment);
        attachment.setKetData(CustomMsgData.newBuilder()
                .subject(subject)
                .image(imageUrl)
                .router(router)
                .title(title)
                .price(price)
                .subtitle(desc)
                .linePrice(linePrice)
                .build());
        IMMessage customMessage = MessageBuilder.createCustomMessage(accid, SessionTypeEnum.P2P, null, attachment, new CustomMessageConfig());
        // send message to server and save to db
        appendPushConfig(customMessage);
        NIMClient.getService(MsgService.class).sendMessage(customMessage, false);
    }

    /**
     * 发送用户首页消息
     *
     * @param accid        发送给谁
     * @param headImageUrl 头像地址
     * @param name
     * @param desc
     * @param router
     */
    public void sendUserHomePageMessage(String accid, String headImageUrl, String name, String desc, String router) {
        UserAttachment attachment = new UserAttachment();
        attachment.setKeyType(CustomMessageType.user);
        attachment.setKetData(CustomMsgData.newBuilder().image(headImageUrl)
                .router(router)
                .title(name)
                .subtitle(desc)
                .build());
        IMMessage customMessage = MessageBuilder.createCustomMessage(accid, SessionTypeEnum.P2P, null, attachment, new CustomMessageConfig());
        // send message to server and save to db
        appendPushConfig(customMessage);
        NIMClient.getService(MsgService.class).sendMessage(customMessage, false);
    }

    /**
     * 单聊会话
     *
     * @param context
     * @param account accid
     */
    public static void startP2PSession(Context context, String account) {
        try {
            if (!AccountUtil.isLogin()) {
                ARouter.getInstance()
                        .build(ARouterConfig.LoginPage)
                        .navigation();
                return;
            }
            if (!AccountUtil.isNimLogin()) {
                String userInfo = JsonUtil.toString(AccountUtil.getCurrentUser());
                CrashUtils.getInstance().netSubmitLog(AiyigeExceptionModel.type_im_login_exception, userInfo, AiyigeExceptionModel.rating_2);
//                return;
            }

            if (TextUtils.isEmpty(account)) {
                ToastX.show(MyApp.getAppContext().getString(R.string.invalid_accid));
                return;
            }
            if (AccountUtil.getLoginInfo() != null && !TextUtils.isEmpty(AccountUtil.getLoginInfo().getAccount())
                    && AccountUtil.getLoginInfo().getAccount().equals(account)) {
                ToastX.show(MyApp.getAppContext().getString(R.string.can_not_chat_with_yourself));
                return;
            }
            NimUIKit.startP2PSession(context, account);
        } catch (Exception e) {

        }
    }

    private void appendPushConfig(IMMessage message) {
        CustomPushContentProvider customConfig = NimUIKitImpl.getCustomPushContentProvider();
        if (customConfig != null) {
            String content = customConfig.getPushContent(message);
            Map<String, Object> payload = customConfig.getPushPayload(message);
            if (!TextUtils.isEmpty(content)) {
                message.setPushContent(content);
            }
            if (payload != null) {
                message.setPushPayload(payload);
            }
        }
    }


    /**
     * 联系客服
     * @param context
     */
    public void imService(final Context context) {
        String accid = ListUtil.isEmpty(LoginManager.getInstance().getServiceList())?null:LoginManager.getInstance().getServiceList().get(0).getAccid();
        if (!TextUtils.isEmpty(accid)) {
            SessionHelper.startP2PSession(context, accid);
        } else {
            // 如果系统启动没有取到，则临时取
            Handler handler = new Handler(){
                @Override
                public void handleMessage(Message msg) {
                    String accid = ListUtil.isEmpty(LoginManager.getInstance().getServiceList())?null:LoginManager.getInstance().getServiceList().get(0).getAccid();
                    if (!TextUtils.isEmpty(accid)) {
                        SessionHelper.startP2PSession(context, accid);
                    }
                }
            };
            LoginManager.getInstance().getServiceACCIDList(handler);
        }
    }
}
